package handlers

import (
	"edgex_back_management/dbops"
	"edgex_back_management/defs"
	"edgex_back_management/model"
	"edgex_back_management/session"
	"encoding/json"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"gopkg.in/mgo.v2"
	"html/template"
	"log"
	"net/http"
)

// 该处理对于已经登录的用户(有session), 进行页面跳转到用户页
func IndexHandler(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	userName, err1 := r.Cookie(HeaderOfUserName)
	sessionId, err2 := r.Cookie(HeaderOfSession)

	var isExpired = false
	if sessionId == nil {
		isExpired = true
	} else {
		_, isExpired = session.IsSessionExpired(sessionId.Value)
	}

	// session错误或不存在情况, 解析到登录页
	if err1 != nil || err2 != nil || isExpired {
		page := &model.HomePage{}
		tpl, err := template.ParseFiles("./templates/login.html")
		if err != nil {
			log.Printf("Error of parsing template login.html: %s", err)
			return
		}
		tpl.Execute(w, page)
		return
	}

	user, err := dbops.FindUserByName(userName.Value)
	if err != nil {
		log.Printf("Error of dbops.FindUserByName: %s", err)
	}

	page := &model.SimpleUser{UserName: user.UserName, AvatarUrl: user.AvatarUrl}
	tpl, err := template.ParseFiles("./templates/home.html")
	if err != nil {
		log.Printf("Error of parsing template home.html: %s", err)
		return
	}

	tpl.Execute(w, page)
	return
}

func Login(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

	err := r.ParseForm()
	if err != nil {
		log.Printf("Error of parse from: %v", err)
		defs.SendErrorResponse(w, defs.ErrorRequestBodyParseFailed)
		return
	}
	userName := r.PostFormValue("userName")
	password := r.PostFormValue("password")

	// Request parse: application/json
	//user := &model.User{}
	//res, _ := ioutil.ReadAll(r.Body)
	//
	//if err := json.Unmarshal(res, user); err != nil {
	//	defs.SendErrorResponse(w, defs.ErrorRequestBodyParseFailed)
	//	return
	//}
	//userName := user.UserName
	user, err := dbops.FindUserByName(userName)

	if err == mgo.ErrNotFound {
		log.Printf("error of resource not found of user: %s: %v", userName, err)
		defs.SendErrorResponse(w, defs.ErrorNotFound)
		return
	}

	if err != nil {
		defs.SendErrorResponse(w, defs.ErrorDBError)
		log.Printf("error of find user by name: %v", err)
		return
	}

	if user.Password != password {
		defs.SendErrorResponse(w, defs.ErrorNotAuthUser)
		return
	}

	sessionId := session.GenerateNewSession(user.UserName)
	signedUp := model.SignedUp{Success: "1", SessionId: sessionId}

	if _, err := json.Marshal(signedUp); err != nil {
		defs.SendErrorResponse(w, defs.ErrorInternalFaults)
		return
	} else {
		cookie1 := http.Cookie{Name: HeaderOfSession, Value: sessionId, Path: "/", MaxAge: 60 * 60}
		cookie2 := http.Cookie{Name: HeaderOfUserName, Value: user.UserName, Path: "/", MaxAge: 60 * 60}
		http.SetCookie(w, &cookie1)
		http.SetCookie(w, &cookie2)
		w.Header().Set(HeaderOfUserName, userName)
		w.Header().Set(HeaderOfSession, sessionId)

		http.Redirect(w, r, "/user/home", 302)
		//defs.SendSuccessResponse(w, string(result), 200)
		return

	}
}

func HomeHandler(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

	userName := r.PostFormValue("userName")
	fmt.Println("HomeHandler:", userName)

	HName, err1 := r.Cookie(HeaderOfUserName)
	if err1 != nil || HName == nil {
		log.Printf("Error of get cookies: %v", err1)
	}

	user, _ := dbops.FindUserByName(HName.Value)

	tpl, err := template.ParseFiles("./templates/home.html")
	if err != nil {
		log.Printf("Error of parsing template home.html: %s", err)
		return
	}
	page := &model.SimpleUser{UserName: user.UserName, AvatarUrl: user.AvatarUrl}
	tpl.Execute(w, page)
	return
}

func Logout(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	userName := params.ByName("userName")
	userSession, err := dbops.FindOneSessionByName(userName)
	if err != nil {
		defs.SendErrorResponse(w, defs.ErrorDBError)
		return
	}
	sessionId := userSession.Id
	session.DeleteSession(sessionId)

	sessionOfId := http.Cookie{Name: HeaderOfSession, Path: "/", MaxAge: -1}
	sessionOfUserName := http.Cookie{Name: HeaderOfUserName, Path: "/", MaxAge: -1}
	http.SetCookie(w, &sessionOfId)
	http.SetCookie(w, &sessionOfUserName)

	logout := model.Logout{Success: "ok", UserName: userName, Message: "再见"}
	if jsonData, err := json.Marshal(logout); err != nil {
		defs.SendErrorResponse(w, defs.ErrorInternalFaults)
		return
	} else {
		defs.SendSuccessResponse(w, string(jsonData), 200)
	}
}

func FindUserInfo(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	userName := params.ByName("userName")

	simpleUser := &model.SimpleUser{}
	user, err := dbops.FindUserByName(userName)
	if err != nil {
		defs.SendErrorResponse(w, defs.ErrorDBError)
		return
	}

	simpleUser.UserName = user.UserName
	simpleUser.AvatarUrl = user.AvatarUrl

	if result, err := json.Marshal(simpleUser); err != nil {
		defs.SendErrorResponse(w, defs.ErrorInternalFaults)
		return
	} else {
		defs.SendSuccessResponse(w, string(result), 200)
	}
}
